import scrapy
from tutorial.items import QuoteItem

from scrapy.cmdline import execute


class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    # 允许爬取的域名，如果初始或后续的请求链接不是这个域名下的，则请求链接会被过滤掉。
    allowed_domains = ['quotes.toscrape.com']
    # 启动时爬取的 url 列表，初始请求是由它来定义的
    start_urls = ['http://quotes.toscrape.com/']

    # 解析
    def parse(self, response):
        """
        默认情况下，被调用时 start_urls 里面的链接构成的请求完成下载执行后，
        返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应、
        提取数据或者进一步生成要处理的请求。
        :param response:
        :return:
        """
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            # class 为text，结果是整个带有标签的节点
            # 获取它的正文内容，可以加 ::text 来获取，结果是列表
            # extract_first 获得列表中第一个元素
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            # extract 获取列表中所有值
            item['tags'] = quote.css('tags .tag::text').extract()
            yield item

        # 首先通过 CSS 选择器获取下一个页面的链接，即要获取 a 超链接中的 href 属性。
        # 这里用到了 ::attr (href) 操作。然后再调用 extract_first 方法获取内容。
        next = response.css('.pager .next a::attr("href")').extract_first()
        # urljoin () 方法可以将相对 URL 构造成一个绝对的 URL
        url = response.urljoin(next)
        # 构造请求时需要用到 scrapy.Request
        # url：它是请求链接
        # callback：它是回调函数。当指定了该回调函数的请求完成之后，
        # 获取到响应，引擎会将该响应作为参数传递给这个回调函数。
        # 回调函数进行解析或生成下一个请求，回调函数如上文的 parse () 所示。
        yield scrapy.Request(url=url, callback=self.parse)